<template>
  <view class="search-result-list-container">
    <empty-data v-if="isEmpty"></empty-data>
    <!-- 1. 通过 mescroll-body 包裹列表，指定 ref 为 mescrollRef ，监听@init、@down、@up 事件 -->
    <!-- 循环渲染列表数据 -->
    <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" v-else>
      <block v-for="(item, index) in resultList" :key="index">
        <view class="search-result-item-box" @click="onClickItem(item)">
          <!-- 内容区 - 样式 1 -->
          <search-result-item-theme-1 v-if="!item.pic_list || item.pic_list.length === 0" :data="item" />
          <!-- 内容区 - 样式 2 -->
          <search-result-item-theme-2 v-else-if="item.pic_list.length === 1" :data="item" />
          <!-- 内容区 - 样式 3 -->
          <search-result-item-theme-3 v-else :data="item" />
          <!-- / -->`
        </view>
      </block>
    </mescroll-body>
  </view>
</template>

<script>
import { _getSearchResult } from '../../api/search.js'
// 2. 导入对应的 mixins
import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'
export default {
  name: 'search-result-list',
  // 3.注册mixins
  mixins: [MescrollMixin],
  props: {
    searchVal: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      p: 1, // 分页页数
      resultList: [], // 搜索结果
      // 实例
      mescroll: null,
      // 定义判断，页面首次创建和处理渲染，会回调 down和up 方法，为了避免该问题，定义 init 变量，表示当前是否为首次请求
      isInit: true,
      isEmpty: false // 空数据展示
    }
  },
  created() {
    // this.getSearchResult()
  },
  mounted() {
    this.mescroll = this.$refs.mescrollRef.mescroll
  },
  methods: {
    /**
     * 搜索结果
     */
    async getSearchResult() {
      const { list } = await _getSearchResult({ q: this.searchVal, p: this.p })
      /**
       * 这里不能直接在css中去定义em的样式，因为标题和内容是放在rich-text中去解析的，最终的内容还是被解析放在rich-text nodes属性中，并没有生成真正的标签
       * 所以css不会生效，可以在控制台中查看解析的内容有没有被解析成dom标签
       *
       * 最终解决方法：
       * 在 `title` 字段下，搜索关键字都通过 `em` 标签进行了标记，所以所谓的 **搜索关键字高亮** 就是 **对 `em` 标签添加高亮样式**
       */
      list.forEach(item => {
        // 全局匹配em 添加行内样式，行内样式可以被rich-text解析
        item.title = item.title.replace(/<em>/g, "<em style='color:#f94d2a; margin:0 2px'>")
        item.description = item.description.replace(/<em>/g, "<em style='color:#f94d2a; margin:0 2px'>")
      })
      // 判断下拉刷新，和上拉加载的赋值操作，
      if (this.p === 1) {
        // 下拉刷新重新赋值第一页数据
        this.resultList = list
      } else {
        // 上拉加载，原有的基础上往后添加
        this.resultList = [...this.resultList, ...list]
      }
      // 长度0说明无搜索结果
      if (this.resultList.length === 0) {
        this.isEmpty = true
      }
    },
    // 4.实现三个回调方法
    /**
     * 首次加载
     */
    async mescrollInit() {
      await this.getSearchResult() // getSearchResult是异步的方法，这里我们需要等待getSearchResult执行后再往下执行，所以使用 await async
      this.isInit = false // 表示首次加载后就允许上拉和下拉加载
      // 关闭 上拉加载 && 下拉刷新动画
      this.mescroll.endSuccess()
      console.log('mescrollInit')
    },
    /**
     * 下拉刷新的回调
     */
    async downCallback() {
      if (this.isInit) return // 解决 页面初次创建时会自动调用该回调，首次不需要自动调用下拉刷新
      // 下拉刷新页数重置成第一页数据
      this.p = 1
      await this.getSearchResult()
      this.mescroll.endSuccess()
      console.log('downCallback')
    },
    /**
     * 上拉加载的回调
     */
    async upCallback() {
      if (this.isInit) return // 解决 页面初次创建时会自动调用该回调，首次不需要自动调用下拉刷新
      // 关闭 上拉加载 && 下拉刷新动画
      this.p += 1
      await this.getSearchResult()
      this.mescroll.endSuccess()

      console.log('upCallback')
    },
    /**
     * 跳转到文章详情
     */
    onClickItem(item) {
      uni.navigateTo({ url: `/subpkg/pages/blog-detail/blog-detail?author=${item.author}&articleId=${item.id}` })
    }
  }
}
</script>

<style lang="scss" scoped>
.search-result-list-container {
  padding: $uni-spacing-col-lg $uni-spacing-row-lg;
  .search-result-item-box {
    margin-bottom: $uni-spacing-col-big;
  }
}
</style>
